package com.fenxiang.tieba.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.fenxiang.tieba.model.*;
import com.fenxiang.tieba.model.wrapper.*;
import com.fenxiang.tieba.utils.*;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.image.ImageView;
import javafx.scene.layout.AnchorPane;
import javafx.stage.FileChooser;
import javafx.stage.Stage;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;

import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.*;
import java.util.logging.Logger;

import static com.fenxiang.tieba.config.PostConfig.USER_COOKIE;
import static com.fenxiang.tieba.config.PostConfig.configMap;
import static com.fenxiang.tieba.config.URLConfig.*;

/**
 * Created by lixiang on 09/07/2017.
 */
public class postController implements Initializable {

    public static Logger logger = Logger.getLogger(postController.class.toString());


    @FXML
    public TextArea postContent;

    @FXML
    public TableView tbPostRecordTable;


    @FXML
    public TableView<BaiDuAccount> bind_accounts_table;

    @FXML
    public ListView titleListView;

    @FXML
    public ListView contentListView;

    @FXML
    public TextArea machine_tbName;

    @FXML
    public TextArea userCookieText;


    @FXML
    public ListView replyListView;

    @FXML
    public ChoiceBox replyTimeSet;

    @FXML
    public TextField replyMount;


    private Stage stage;


    private ObservableList<PostRecord> recordsData = FXCollections.observableArrayList();

    private ObservableList<BaiDuAccount> accountsData = FXCollections.observableArrayList();

    private ObservableList<TieBaPost> postsData = FXCollections.observableArrayList();


    /**
     * 把userCookie放入到configMap里面去
     *
     * @param actionEvent
     */
    public void bindUserByCookie(ActionEvent actionEvent) {

        String userCookie = userCookieText.getText();
        configMap.put(USER_COOKIE, userCookie);
        JSONObject personInfoJson = TieBaUtils.getPersonInfo();
        String userName = personInfoJson.getJSONObject("data").getString("user_name_show");
        FX_FXUtils.showTimedDialog(3000,"欢迎您 ："+userName);
        logger.info(personInfoJson.toJSONString());

    }

    public void uploadImage(ActionEvent actionEvent) {
        CloseableHttpClient httpclient = HttpClients.createDefault();
        try {
            FileChooser fileChooser = new FileChooser();
            FileChooser.ExtensionFilter extFilter = new FileChooser.ExtensionFilter("all files (*.*)", "*.*");
            fileChooser.getExtensionFilters().add(extFilter);
            File file = fileChooser.showOpenDialog(stage);
            JSONObject tbsReturn = HttpUtils.getAsJson(IMG_TBS_URL, null);
            //先获取到上传图片的tbs ， 然后再开始上传图片
            String imageTbs = tbsReturn.getJSONObject("data").getString("tbs");
            LinkedHashMap<String, String> map = new LinkedHashMap<>();
            map.put("tbs", imageTbs);
            map.put("save_yun_album", "1");
            JSONObject uploadImageReturn = HttpUtils.postMultipartAsJson(POST_IMAGE_URL, map, "file", file);
            String uploadImageUrl = uploadImageReturn.getJSONObject("info").getString("pic_water");
            String uploadImageUrl_height = uploadImageReturn.getJSONObject("info").getString("fullpic_height");
            String uploadImageUrl_width = uploadImageReturn.getJSONObject("info").getString("fullpic_width");
            String uploadImageUrl_type = uploadImageReturn.getJSONObject("info").getString("pic_type");
            String imageContent = "[br][img pic_type=" + uploadImageUrl_type + " width=" + uploadImageUrl_width
                    + " height=" + uploadImageUrl_height + "]" + uploadImageUrl + "[/img]";
            postContent.appendText(imageContent);
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    /**
     * 发表新贴
     *
     * @param actionEvent
     */
    public void postThread(ActionEvent actionEvent) {

    }

    /**
     * 对已有的贴子进行回复
     *
     * @param actionEvent
     */
    public void replyPost(ActionEvent actionEvent) {

    }


    @Override
    public void initialize(URL location, ResourceBundle resources) {

        //初始化系统配置
        initSysConfig();


        //初始化读取系统已导入的用户
        initExitsUser();

        //初始化读取系统已导入的内容
        initExitsPost();

        //初始化读取系统的发贴记录
        initExitsRecord();


//        personData.addAll(XMLUtils.loadFromFile("post.xml",PostRecordWrapper.class).getList());
//        tbNameColumn.setCellValueFactory(cellData->cellData.getValue().tbNameProperty());
//        tbTitleColumn.setCellValueFactory(cellData->cellData.getValue().titleProperty());
//        tbIdColumn.setCellValueFactory(cellData->cellData.getValue().tidProperty());
//        tbContentColumn.setCellValueFactory(cellData->cellData.getValue().contentProperty());
//        tbPostTable.setItems(personData);
//
//        Function<PostRecord,ObservableValue<PostRecord>> property =ReadOnlyObjectWrapper<PostRecord>::new;
//
//        tbActionColumn.setCellValueFactory(cellData->property.apply(cellData.getValue()));
//        tbActionColumn.setCellFactory(col->{
//            Button editButton = new Button("任务操作");
//            TableCell<PostRecord, PostRecord> cell = new TableCell<PostRecord, PostRecord>() {
//                @Override
//                public void updateItem(PostRecord postRecord, boolean empty) {
//                    super.updateItem(postRecord, empty);
//                    if (empty) {
//                        setGraphic(null);
//                    } else {
//                        setGraphic(editButton);
//                    }
//                }
//            };
//
//            editButton.setOnAction(e -> setTaskStage(cell.getItem()));
//
//            return cell ;
//
//        });

    }

    /**
     * 初始化系统配置
     */
    private void initSysConfig() {
        //读取resources目录的文件，并且将其复制到外部的config目录下
        //以后对文件的操作，全部是对外部文件的操作
        FX_FileUtils.convertIstoFile("conf/posts.xml");
        FX_FileUtils.convertIstoFile("conf/postRecords.xml");
        FX_FileUtils.convertIstoFile("conf/replies.xml");
        FX_FileUtils.convertIstoFile("conf/accounts.xml");

        //初始化设置回贴的时间间隔
        replyTimeSet.setItems(FXCollections.observableArrayList("15分钟","30分钟","60分钟"));
        replyTimeSet.setValue("30分钟");

    }


    public void setTaskStage(PostRecord item) {
        ////整个窗体的设置
        Stage verifyStage = new Stage();
        AnchorPane anchorPane = new AnchorPane();
        Scene scene = new Scene(anchorPane, 430, 350);
        verifyStage.setTitle("验证码");
        verifyStage.setScene(scene);
        verifyStage.show();

        ImageView verifyImage = new ImageView();
        verifyImage.setLayoutX(10);
        verifyImage.setLayoutY(80);
        anchorPane.getChildren().add(verifyImage);

        TextField verifyCode = new TextField();
        verifyCode.setLayoutX(10);
        verifyCode.setLayoutY(10);
        anchorPane.getChildren().add(verifyCode);

        Button submitVerifyCode = new Button("提交");
        submitVerifyCode.setLayoutX(200);
        submitVerifyCode.setLayoutY(10);
        anchorPane.getChildren().add(submitVerifyCode);


        System.out.println(JSON.toJSONString(item));

    }

    //选择文件进行账号的导入，先导入，然后生成自己的配置文件
    public void bindUserFromFile(ActionEvent actionEvent) {


        File file = FX_FXUtils.openFileChooser(stage);
        BaseWrapper<BaiDuAccount> bdAccountWrapper = XMLUtils.loadFromFile(file, BaiDuAccountWrapper.class);
        //读取完之后进行保存，然后再调用initExitsUser方法
        XMLUtils.saveToFile(bdAccountWrapper, "accounts.xml", BaiDuAccountWrapper.class);
        initExitsUser();

    }

    //绑定用户页面初始化用户
    public void initExitsUser() {

        try {
            BaseWrapper<BaiDuAccount> baiDuAccountBaseWrapper = XMLUtils.loadFromFile("accounts.xml", BaiDuAccountWrapper.class);
            if (baiDuAccountBaseWrapper != null) {
                accountsData.addAll(baiDuAccountBaseWrapper.getList());
                //如果数据不为空，则和tabView进行绑定
                Map<String, String> pairMap = new HashMap<>();
                pairMap.put("account_userName", "userName");
                pairMap.put("account_password", "password");
                pairMap.put("account_cookie", "cookie");
                FX_FXUtils.bindListToTableView(accountsData, bind_accounts_table, pairMap);
            }
        } catch (Exception e) {
           logger.warning("读取已存在用户失败");
        }

    }

    //绑定用户页面初始化发贴的标题和内容
    public void initExitsPost() {
        try{
            TieBaPostWrapper postBaseWrapper = (TieBaPostWrapper) XMLUtils.loadFromFile("posts.xml", TieBaPostWrapper.class);
            if (postBaseWrapper != null) {
                ObservableList<String> titleList = FXCollections.observableArrayList(postBaseWrapper.getTitle());
                ObservableList<String> contentList = FXCollections.observableArrayList(postBaseWrapper.getContent());
                titleListView.setItems(titleList);
                contentListView.setItems(contentList);

            }
        }catch (Exception e){
            logger.warning("读取已存在的发贴内容失败");
        }



    }

    //绑定发贴记录页面发过的贴子，对应的文件是：postRecords.xml
    private void initExitsRecord() {
        try {
            BaseWrapper<PostRecord> postRecordBaseWrapper = XMLUtils.loadFromFile("postRecords.xml", PostRecordWrapper.class);
            if (postRecordBaseWrapper != null) {
                recordsData.addAll(postRecordBaseWrapper.getList());
                //如果数据不为空，则和tabView进行绑定
                Map<String, String> pairMap = new HashMap<>();
                pairMap.put("tbIdColumn", "tid");
                pairMap.put("tbNameColumn", "tbName");
                pairMap.put("tbTitleColumn", "title");
                pairMap.put("tbContentColumn", "content");
                FX_FXUtils.bindListToTableView(recordsData,tbPostRecordTable,pairMap);
            }
        } catch (Exception e) {
            logger.warning("读取已发贴子记录失败");
        }
    }

    //从文件导入要发贴的标题和内容
    public void loadContentFromFile(ActionEvent actionEvent) {

        File file = FX_FXUtils.openFileChooser(stage);
        if (file != null) {
            BaseWrapper<TieBaPost> postWrapper = XMLUtils.loadFromFile(file, TieBaPostWrapper.class);

            //读取完之后进行保存，然后再调用initExitsUser方法
            XMLUtils.saveToFile(postWrapper, "posts.xml", TieBaPostWrapper.class);
            initExitsPost();
        }

    }


    public void showPostConfig(ActionEvent actionEvent) {
        Stage configStage = new Stage();
        //加载资源文件,用于定义界面
        Parent root = null;
        try {
            root = FXMLLoader.load(getClass().getResource("/postConfig.fxml"));
        } catch (IOException e) {
            e.printStackTrace();
        }
        //整个窗体的设置
        configStage.setTitle("发贴设置");
        configStage.setScene(new Scene(root, 600, 400));
        configStage.show();
    }

    /**
     * 开始发贴
     *
     * @param actionEvent
     */
    public void beginPost(ActionEvent actionEvent) {
        //读取默认的配置
        //todo:


        //随机获取到title和content
        ObservableList<String> titleList = titleListView.getItems();
        String title = FX_ListUtils.getRandomValueFromList(titleList);

        ObservableList<String> contentList = contentListView.getItems();
        String content = FX_ListUtils.getRandomValueFromList(contentList);


        //获取贴吧列表
        String[] tbNames = machine_tbName.getText().split("\n");

        System.out.println(title + " " + content + " " + JSON.toJSONString(tbNames));


        //开始循环发贴

        for (String tbName : tbNames) {
           JSONObject postReturn =  TieBaUtils.postNewThread(tbName, title, content);

           String tid = postReturn.getJSONObject("data").getString("tid");
            //发贴完成之后，获取贴子的tid ， 然后进行生成postRecord进行保存
            //两种方案，1是直接更新list ，程序关闭后不能保存。2是更新文件。
            PostRecord record = new PostRecord();
            record.setTid(tid);
            record.setContent(content);
            record.setTbName(tbName);
            record.setTitle(title);
            XMLUtils.addToFile(record, "postRecords.xml",PostRecordWrapper.class);
            //更新完文件之后，重新初始化读取一次文件
            initExitsRecord();
            System.out.println(postReturn);
        }


    }

    //开始回复
    public void beginReply(ActionEvent actionEvent) {

        //先生成一个Task任务，放到taskList里面
        // 然后通过id号，判断其状态来决定线程要不要继续执行

        FX_FXUtils.showTimedDialog(3000,"已开始回复，请到任务面板查看");



        //开启一个新的线程去执行回贴的任务
        Runnable replyRunable = ()->{

            // 获取回贴条数，并以此进行循环的判断
            int replyCount = Integer.valueOf(replyMount.getText().trim());

            while (0 < replyCount--){

                //从tableView中获得贴吧名和tid
                PostRecord postRecord= (PostRecord) tbPostRecordTable.getSelectionModel().getSelectedItem();
                String tid = postRecord.getTid();
                String tbName = postRecord.getTbName();

                //随机选择一条回复
                ObservableList<String> replyList = replyListView.getItems();
                String reply = FX_ListUtils.getRandomValueFromList(replyList);
                int replyTimeIndex = replyTimeSet.getSelectionModel().getSelectedIndex();


                //生成reply实体类
                TieBaReply tieBaReply = new TieBaReply(tbName,tid,reply);
                TieBaUtils.postNewReply(tieBaReply);
                try {
                   switch (replyTimeIndex){
                       case 0 :
                           //15分钟=900000，测试时为5分钟300000
                           Thread.sleep(300000);
                   }
                    Thread.sleep(3000);


                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

            }


        };

        Thread replyThread = new Thread(replyRunable);
        replyThread.start();

       //
    }

    //从文件中导入回复，这个不记录在系统，每次启动都需要导入
    public void loadReplyFromFile(ActionEvent actionEvent) {
        File file = FX_FXUtils.openFileChooser(stage);
        if (file != null) {
            TieBaReplyWrapper replyBaseWrapper = (TieBaReplyWrapper) XMLUtils.loadFromFile(file, TieBaReplyWrapper.class);
            //读取完之后进行显示
            ObservableList<String> replyList = FXCollections.observableArrayList(replyBaseWrapper.getReply());
            replyListView.setItems(replyList);
        }
    }
}
